from extractor import extract_data_by_channel_mapping, extract_line_data, extract_bus_data, extract_transformer_data, \
    convert_inf_to_dmf_format
from fault_detect import FaultDetectionSystem, FaultDetectionConfig
from model.FaultDetectionResult import FaultDetectionResult
from parser.cfg_parser import CfgParser
from parser.dat_parser import Data_file
from parser.unified_parser import DeviceConfigManager


class ComprehensiveFaultDetector:
    """综合故障检测器"""

    def __init__(self, file_name: str, data_dir: str = 'data'):
        """
        初始化故障检测器

        Args:
            file_name: 文件名（不含扩展名）
            data_dir: 数据目录
        """
        self.file_name = file_name
        self.data_dir = data_dir
        self.dmf_file = f'{data_dir}/{file_name}.DMF'
        self.inf_file = f'{data_dir}/{file_name}.INF'
        self.cfg_file = f'{data_dir}/{file_name}.cfg'

        # 初始化组件
        self.cfg_obj = None
        self.device_config = None
        self.data_source = None
        self.line_data = None
        self.transformer_data = None
        self.bus_data = None
        self.data_file = None
        self.df = None
        self.extracted_data = None
        self.config = None
        self.fd_system = None

        print(f"初始化故障检测器: {file_name}")

    def load_and_parse_files(self):
        """加载和解析所有文件"""
        print("=" * 60)
        print("1. 解析配置文件")
        print("=" * 60)

        # 解析CFG文件
        self.cfg_obj = CfgParser(self.cfg_file)
        if not self.cfg_obj.parse():
            raise ValueError(f"CFG文件解析失败: {self.cfg_file}")

        # self.cfg_obj.print_summary()

        print("\n" + "=" * 60)
        print("2. 解析设备配置文件")
        print("=" * 60)

        # 使用统一解析器加载设备配置
        self.device_config = DeviceConfigManager(self.data_dir, self.file_name)

        if not self.device_config.load_config(prefer_dmf=True):
            raise ValueError(f"设备配置文件加载失败: {self.file_name}")

        self.data_source = self.device_config.get_data_source()

        # 打印配置摘要
        # summary = self.device_config.get_summary()
        # print(f"✓ 设备配置加载成功:")
        # print(f"  数据源: {summary['data_source']}")
        # print(f"  线路: {summary['lines_count']} 条")
        # print(f"  母线: {summary['buses_count']} 个")
        # print(f"  变压器: {summary['transformers_count']} 个")

        return True

    def load_and_process_data(self):
        """加载和处理数据文件"""

        # 创建数据文件对象
        self.data_file = Data_file(self.cfg_obj)
        if not self.data_file.check_file():
            raise ValueError("数据文件不存在或校验失败")

        # 解析数据（可用唯一列名处理）
        self.data_file.parse_data()
        self.data_file.get_channels_data()

        # 导出为DataFrame
        self.df = self.data_file.export_data()

        return True

    def extract_device_data(self):
        """提取所有设备数据（线路、母线、变压器）"""
        print("\n" + "=" * 60)
        print("4. 提取设备数据")
        print("=" * 60)

        # 使用统一解析器获取设备数据
        if self.data_source == 'INF':
            # INF数据需要转换为DMF格式
            raw_parser = self.device_config.get_raw_data()
            converted_dmf_data = convert_inf_to_dmf_format(raw_parser)
            print("✓ INF数据已转换为DMF兼容格式")

            # 提取设备数据
            self.line_data = extract_line_data(converted_dmf_data)
            self.bus_data = extract_bus_data(converted_dmf_data, self.df)
            self.transformer_data = extract_transformer_data(converted_dmf_data, self.df)

        else:
            # DMF数据直接使用
            raw_dmf_data = self.device_config.get_raw_data()

            self.line_data = extract_line_data(raw_dmf_data)
            self.bus_data = extract_bus_data(raw_dmf_data, self.df)
            self.transformer_data = extract_transformer_data(raw_dmf_data, self.df)

        print(f"提取到设备信息:")
        print(f"  线路: {len(self.line_data)} 条")
        print(f"  母线: {len(self.bus_data)} 个")
        print(f"  变压器: {len(self.transformer_data)} 个")

        # 提取线路时间序列数据
        self.extracted_data = extract_data_by_channel_mapping(
            self.line_data,
            self.df
        )

        return True

    def initialize_fault_detection_system(self):
        """初始化故障检测系统"""
        print("\n" + "=" * 60)
        print("5. 初始化故障检测系统")
        print("=" * 60)

        # 获取采样率
        fs = max(self.cfg_obj.sample_rate_points[0])
        freq = self.cfg_obj.reference_frequency

        # 创建故障检测配置
        self.config = FaultDetectionConfig(
            fs=fs,
            freq=freq
        )

        # 创建故障检测系统
        self.fd_system = FaultDetectionSystem(self.config)
        print("故障检测系统初始化完成")

        return True

    def detect_all_devices_faults(self):
        """检测所有设备（线路、母线、变压器）的故障"""
        print("\n" + "=" * 60)
        print("7. 执行故障检测")
        print("=" * 60)

        if self.fd_system is None:
            raise ValueError("请先初始化故障检测系统")

        results = []

        # 1. 检测线路故障
        print("\n=== 检测线路故障 ===")
        line_results = self._detect_lines_faults()
        results.extend(line_results)

        # for line_result in line_results:
        #     if line_result.fault_detected:
        #         details = line_result.details
        #         plot_phasors_polar(
        #             angles=details.get('phase_angles', None),
        #             magnitudes=details.get('phase_magnitudes', None),
        #             title=f"{line_result.line_name} 相量图"
        #         )

        # # 2. 检测母线故障
        # if self.bus_data:
        #     print("\n=== 检测母线故障 ===")
        #     bus_results = self._detect_buses_faults()
        #     results.extend(bus_results)
        #
        # # 3. 检测变压器故障
        # if self.transformer_data:
        #     print("\n=== 检测变压器故障 ===")
        #     transformer_results = self._detect_transformers_faults()
        #     results.extend(transformer_results)

        return results

    def _detect_lines_faults(self):
        """检测线路故障"""
        results = []

        for line_name, branches in self.extracted_data.items():
            for branch_index, branch_data in enumerate(branches):
                result = self._detect_single_device_fault(
                    device_name=line_name,
                    device_type="线路",
                    combined_data=branch_data.get('combined_data', None)
                )

                if result:
                    results.append(result)

        return results

    def _detect_transformers_faults(self):
        """检测变压器故障"""
        results = []

        for trm_name, trm_data in self.transformer_data.items():
            print(f"\n检测变压器: {trm_name}")

            result = self._detect_single_device_fault(
                device_name=trm_name,
                device_type="变压器",
                combined_data=trm_data.get('combined_data', None)
            )

            if result:
                results.append(result)

        return results

    def _detect_single_device_fault(self, device_name, device_type, combined_data):
        """检测单个设备的故障"""
        if combined_data is None or combined_data.empty:
            print(f"    警告: {device_type} {device_name} 无有效数据")
            return None

        try:
            # 执行故障检测
            res = self.fd_system.detect_fault_type(
                combined_data,
                self.cfg_obj
            )

            # 创建结果对象
            result = FaultDetectionResult(
                line_name=device_name,
                fault_detected=res.fault_type.value != "未知",
                fault_type=res.fault_type.value,
                details=res.details
            )

            # 添加设备类型信息
            result.details['device_type'] = device_type

            return result

        except Exception as e:
            print(f"    错误: 故障检测失败 - {e}")
            raise e

    def run_complete_analysis(self):
        """运行完整的故障检测分析"""
        try:
            # 1. 加载和解析文件
            self.load_and_parse_files()

            # 2. 处理数据文件
            self.load_and_process_data()

            # 3. 提取设备数据
            self.extract_device_data()

            # 4. 初始化故障检测系统
            self.initialize_fault_detection_system()

            # 6. 检测所有线路故障
            return self.detect_all_devices_faults()


        except Exception as e:
            print(f"\n故障检测过程中发生错误: {e}")
            import traceback
            traceback.print_exc()
            return {
                'success': False,
                'error': str(e),
                'results': [],
                'fault_branches': [],
                'data_source': f'{self.data_source}文件' if self.data_source else 'Unknown'
            }